﻿using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;

namespace _3D.Data
{
    public class Game
    {
        private cMaze myMaze = new cMaze();
        private Bitmap myMazeBitmap;
        private Game game;

        private Random rand = new Random();
        private const int MAX_MAZE = 200;
        private int bsx = 512;
        private int bsy = 512;
        private int seed;
        private int msx;
        private int msy;
        private int smooth;
        private int x;
        private int y;

        public void Start(int msx1, int msy1, int smooth1)
        {
            if ((msx1 < 2) || (msx1 > MAX_MAZE) || (msy1 < 2) || (msx1 > MAX_MAZE))
            {
                MessageBox.Show("Valid range for maze size: [2-" + MAX_MAZE.ToString() + "].", "Bad parameters", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
         
            if ((smooth1 < 0) || (smooth1 > 30))
            {
                MessageBox.Show("Valid range for smoothness: [0-30].", "Bad parameters", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            msx = msx1;
            msy = msy1;
            seed = rand.Next(32000);
            smooth = smooth1;

            //create maze
            myMaze.GenerateMaze(msx, msy, seed, smooth);
            myMazeBitmap = myMaze.GetBitmap(bsx, bsy);
        }

        public ArrayList Solve()
        {
            if (myMaze == null)
            {
                MessageBox.Show("The maze has to be created first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return null;
            }
            else
            {
                return myMaze.Solve(0, 0, myMaze.MSIZEX - 1, myMaze.MSIZEY - 1);
            }
        }

        public void Save(string name, int _x, int _y)
        {
            Data.WriteFile(myMaze, msx, msy, seed, smooth, name, _x, _y);
        }

        public void Load(ref int _msx, ref int _msy, ref int _smooth, string name, ref int _x, ref int _y)
        {
            Data.ReadFile(ref myMaze, ref msx, ref msy, ref seed, ref smooth, name, ref x, ref y);
            _msx = msx;
            _msy = msy;
            _smooth = smooth;
            _x = x;
            _y = y;

            myMaze.GenerateMaze(msx, msy, seed, smooth);
            myMazeBitmap = myMaze.GetBitmap(bsx, bsy);
        }

        public void Serialize(Game _game, int _x, int _y, string name)
        {
            x = _x;
            y = _y;
            XMLSerialize.Serialize(_game, name);
        }

        public void Deserialize(ref int _msx, ref int _msy, ref int _smooth, string name, ref int _x, ref int _y)
        {
            XMLSerialize.Deserialize(ref game, name);

            _msx = msx = game.msx;
            _msy = msy = game.msy;
            _smooth = smooth = game.smooth;
            _x = x = game.x;
            _y = y = game.y;
            seed = game.seed;

            myMaze.GenerateMaze(msx, msy, seed, smooth);
            myMazeBitmap = myMaze.GetBitmap(bsx, bsy);
        }

        public Image GetBitmap()
        { return myMazeBitmap; }

        public bool CheckConnect(int x1, int y1, string direction)
        {
            return myMaze.CheckConnect(x1, y1, direction);
        }

        public class cCellPosition
        {
            public int x, y;
            public cCellPosition() { }
            public cCellPosition(int xp, int yp) { x = xp; y = yp; }
        }

        #region GetSet

        public int SEED
        {
            get { return seed; }
            set { seed = value; }
        }

        public int MSX
        { 
            get { return msx; }
            set { msx = value; } 
        }

        public int MSY
        {
            get { return msy; }
            set { msy = value; }
        }

        public int SMOOTH
        {
            get { return smooth; }
            set { smooth = value; }
        }

        public int X
        {
            get { return x; }
            set { x = value; }
        }

        public int Y
        {
            get { return y; }
            set { y = value; }
        }

        #endregion

        public Game(){ }

    }
}
